<?php

abstract class Module_Impl_Abstarct_Opration implements Module_Interface_Opration{
	/**
	 * @var Zend_Db_Adapter_Pdo_Mysql
	 */
	protected $_dbAdapter = null;
	
	protected $_tablename = null;	
	protected $_objectname = null;	
	
	/**
	 * $_magic_field_count['users_id']['table']= 'users'
	 * $_magic_field_count['users_id']['field']= 'orders_count'
	 * $_magic_field_count['users_id']['step']= 1
	 * @var array
	 */
	protected $_magic_field_count = null;
	/**
	 * $_check_field_before_insert['username']= self::FAIL_TO_REGISTER_USER_BECAUSE_USER_HAS_EXISTED
	 * @var array
	 */
	protected $_check_field_before_insert = null;
	
	protected $_needCheckBeforeUpdate = true;
	
	protected $_needCheckBeforeDelete = false;
	
	
	const FAIL_TO_UPDATE_BECAUSE_NO_EXIST = 'update.fail.no.exist';
	const FAIL_TO_DELETE_BECAUSE_NO_EXIST = 'delete.fail.no.exist';
	
	/**
	 * @var Module_Interface_Select
	 */
	protected $_interface_select = null;
	/**
	 * @var Module_Interface_Translate
	 */
	protected $_interface_translate = null;
	
	protected function __construct(){	
		$this->_dbAdapter = Zend_Db_Table::getDefaultAdapter ();
		$this->_interface_translate = Module_Impl_I18n::getInstance();
	}
	
		
	public function setCheckBeforeUpdate($boolean = true) {
		if (is_bool ( $boolean )) {
			$this->_needCheckBeforeUpdate = $boolean;
		}
	}
	
	public function setCheckBeforeDelete($boolean = true) {
		if (is_bool ( $boolean )) {
			$this->_needCheckBeforeDelete = $boolean;
		}
	}
	protected function _insertBefore($info){
		//$this->_check_field_before_insert ['user_id&user_id_in_trushbox'] = self::FAIL_TO_REGISTER_USER_BECAUSE_USER_HAS_EXISTED;
		if (! empty ( $this->_check_field_before_insert ) 
			and is_array ( $this->_check_field_before_insert )) {
			foreach ( $this->_check_field_before_insert as $field => $i18nMsg ) {
				$fields = explode ( '&', $field );
				$fieldValueArray = array ();
				foreach ( $fields as $_field ) {
					$fieldValueArray [$_field] = $info [$_field];
				}
				$check = $this->_isExist ( $fieldValueArray );
				//if the data exists before insert.
				if ($check) {
					$this->_interface_translate->clearErrorMsg();
					$this->_interface_translate->setErrorMsg($field,$i18nMsg);
					return false;
				}
			}
		}
		return true;
	}
	protected function _insertAfter($info){
		/*$this->_magic_field_count['user_id']['table'] = Config_Table::TABLE_USER;
		$this->_magic_field_count['user_id']['field'] = 'user_in_trushbox_count';
		$this->_magic_field_count['user_id']['step']= 1;
		$this->_magic_field_count['user_id_in_trushbox']['table'] = Config_Table::TABLE_USER;
		$this->_magic_field_count['user_id_in_trushbox']['field'] = 'user_be_trushboxed_count';
		$this->_magic_field_count['user_id_in_trushbox']['step']= 1;*/
		if (! empty ( $this->_magic_field_count ) and is_array ( $this->_magic_field_count )) {
			foreach ( $this->_magic_field_count as $key => $value ) {
				if (isset ( $info [$key] )) {
					$this->addCount ( $value ['table'], $value ['field'], $value ['step'], 'id=' . $info [$key] );
				}
			}
		}
	}
	public function insert($info) {
		if(!$this->_insertBefore($info)){
			return false;
		}
		$info ['create_at'] = Util_TimeMath::getDateTime ();
		$info ['created_at'] = Util_TimeMath::getDateTime ();
		$info = Config_Table::getInfo ( $info, $this->_tablename );
		if (isset ( $info ['id'] )) {
			unset ( $info ['id'] );
		}
		try {
			$this->_dbAdapter->insert ( $this->_tablename, $info );
			$id = $this->_dbAdapter->lastInsertId ( $this->_tablename );
		} catch ( Exception $e ) {
			throw $e;
		}
		$this->_insertAfter($info);
		return $id;
	}
	public function update($id, $info) {
		try {
			$result = $this->updateByField ( 'id', $id, $info );
		} catch ( Exception $e ) {
			throw $e;
		}
		return $result;
	}
	protected function _updateBefore($field,$value){
		if ($this->_needCheckBeforeUpdate) {
			$datas = $this->_isExist ( array ($field => $value ) );
			if (! $datas) {
				$this->_interface_translate->clearErrorMsg();
				$this->_interface_translate->setErrorMsg($this->_objectname,self::FAIL_TO_UPDATE_BECAUSE_NO_EXIST);
				return false;
			}
		}
		return true;
	}
	public function updateByField($field, $value, $info) {
		$where = $this->_dbAdapter->quoteInto ( $field . ' = ?', $value );
		$info ['update_at'] = Util_TimeMath::getDateTime ();
		$info ['updated_at'] = Util_TimeMath::getDateTime ();
		$info = Config_Table::getInfo ( $info, $this->_tablename );
		
		if(!$this->_updateBefore($field,$value)){
			return false;
		}
				
		if (isset ( $info ['id'] )) {
			unset ( $info ['id'] );
		}
		try {
			$this->_dbAdapter->update ( $this->_tablename, $info, $where );
		} catch ( Exception $e ) {
			throw $e;
		}
		return true;
	}
	
	public function delete($id) {
		try {
			$result = $this->deleteByField ( 'id', $id );
		} catch ( Exception $e ) {
			throw $e;
		}
		return $result;
	}
	protected function _deleteBefore($field, $value) {
		$datas = null;
		if ($this->_needCheckBeforeDelete) {
			$datas = $this->_isExist ( array ($field => $value ),array(),false );
			if (! $datas) {
				$this->_interface_translate->clearErrorMsg();
				$this->_interface_translate->setErrorMsg($this->_objectname,self::FAIL_TO_DELETE_BECAUSE_NO_EXIST);
				return false;
			}
		}
		/**
		 * $_magic_field_count['user_id']['table']= 'users'
		 * $_magic_field_count['user_id']['field']= 'orders_count'
		 * $_magic_field_count['user_id']['step']= 1
		 */
		if (! empty ( $this->_magic_field_count ) and is_array ( $this->_magic_field_count )) {
			if (empty ( $datas )) {
				$datas = $this->_interface_select->getByField ( $field, $value, array(),false );
			}
			if (! empty ( $datas ) and is_array ( $datas )) {
				foreach ( $datas as $data ) {
					if ($data instanceof Object_Abstract) {
						Zend_Debug::dump($data);
						foreach ( $this->_magic_field_count as $key => $value ) {
							Zend_Debug::dump($key);
							
							$id = $data->$key;
							Zend_Debug::dump($id);
							//$this->addCount ( $value ['table'], $value ['field'], $value ['step'], 'id=' . $id, false );
						}
						die();
					}
				}
			}
		}
		return true;
	}
	public function falseDeleteByField($field, $value ,$info) {
		if(!$this->_deleteBefore( $field, $value )){
			return false;
		}		
		try {
			$this->updateByField($field,$value,$info);
		} catch ( Exception $e ) {
			throw $e;
		}		
		return true;
	}
	
	public function deleteByField($field, $value) {		
		if(!$this->_deleteBefore( $field, $value )){
			return false;
		}		
		try {
			$where = $this->_dbAdapter->quoteInto ( $field . ' = ?', $value );
			$this->_dbAdapter->delete ( $this->_tablename, $where );
		} catch ( Exception $e ) {
			throw $e;
		}		
		return true;
	}
	
	protected function _isExist($fieldValues, $options = array(),$onlyOne = true) {
		if (empty ( $fieldValues )) {
			return false;
		}
		
		$object = $this->_interface_select->getByFieldValueArray ( $fieldValues,$options ,$onlyOne );
		return (! empty ( $object )) ? $object : false;
	}
	
	public function addCount($tablename, $field, $count, $where, $isAdd = true) {
		if ($isAdd) {
			$sql = "update " . $tablename . " set `" . $field . "`=`" . $field . "`+" . $count . " where " . $where;
		} else {
			$sql = "update " . $tablename . " set `" . $field . "`=`" . $field . "`-" . $count . " where " . $where;
		}
		$this->_dbAdapter->query ( $sql );
	}
}